package com.sbw.wx.utils;

import com.alibaba.fastjson.JSONObject;
import com.sbw.wx.config.BaseInfoConfig;
import com.sbw.wx.entity.AccessTokenBean;
import com.sbw.wx.path.RequestPathConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;

/**
 * Desc: AccessToken工具类
 * @Date: 2021/6/27 9:24
 * @Author: Lee
 * 面朝大海  春暖花开
 * */
@Slf4j
@Component
public class AccessTokenUtil {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private BaseInfoConfig baseInfo;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public String getAccessToken(){
        // 从缓存中拿AccessToken, 拿不到或者快要过期再去重新获取然后刷新缓存
        Object redisAccessToken = redisTemplate.opsForValue().get(baseInfo.getAppID());
        if (null == redisAccessToken){
            log.info("当前AccessToken为空，准备获取新的AccessToken");
            AccessTokenBean accessTokenBean = getAccessTokenFromServer();
            return accessTokenBean.getAccessToken();
        } else {
            long expire = redisTemplate.getExpire(baseInfo.getAppID());
            if (expire < 300) {
                log.info("当前AccessToken即将过期，剩余时间:{}，准备获取新的AccessToken");
                AccessTokenBean accessTokenBean = getAccessTokenFromServer();
                return accessTokenBean.getAccessToken();
            }
        }
        return redisAccessToken + "";
    }

    /** 从微信服务器获取AccessToken */
    private AccessTokenBean getAccessTokenFromServer(){
        String url = MessageFormat.format(RequestPathConst.getAccessToken, baseInfo.getAppID(), baseInfo.getAppsSecret());
        ResponseEntity<String> retAccessToken = restTemplate.getForEntity(url, String.class);
        log.info("从微信服务器获取AccessToken返回:{}", retAccessToken.getBody());
        AccessTokenBean tokenBean = JSONObject.parseObject(retAccessToken.getBody(), AccessTokenBean.class);
        redisTemplate.opsForValue().set(baseInfo.getAppID(), tokenBean.getAccessToken(), tokenBean.getExpiresIn(), TimeUnit.SECONDS);
        log.info("更新缓存中的AccessToken, token:{}, expire:{}", tokenBean.getAccessToken(), tokenBean.getExpiresIn());
        return tokenBean;
    }

}
